"""
Base interfaces for the event system.

This module defines the fundamental interfaces for event handling, dispatching,
and filtering. These are the core building blocks of the event system.
"""

from abc import ABC, abstractmethod
from typing import (
    Any,
    Dict,
    List,
    Optional,
    Protocol,
    TypeVar,
    Generic,
    runtime_checkable,
    Callable,
    Awaitable,
)

from continuallearning.events.core.event_types import EventType, BaseEventData

# Type variables for generic event handling
E = TypeVar("E", bound=BaseEventData)
T = TypeVar("T")


# ========== Core Event Handler Interfaces ==========


@runtime_checkable
class EventHandlerInterface(Protocol[E]):
    """
    Core interface for event handlers.

    This protocol defines the minimal contract that all event handlers
    must implement, following the Interface Segregation Principle.
    """

    def can_handle(self, event: E) -> bool:
        """Check if this handler can process the given event."""
        ...

    def handle_event(self, event: E) -> Optional[E]:
        """Handle an event and optionally return a response."""
        ...

    def get_handled_events(self) -> List[EventType]:
        """Get list of event types this handler can process."""
        ...

    @property
    def priority(self) -> int:
        """Handler priority (higher numbers execute first)."""
        ...

    @property
    def name(self) -> str:
        """Handler name for identification."""
        ...


@runtime_checkable
class AsyncEventHandlerInterface(Protocol[E]):
    """Protocol for asynchronous event handlers."""

    def can_handle(self, event: E) -> bool:
        """Check if this handler can process the given event."""
        ...

    async def handle_event(self, event: E) -> Optional[E]:
        """Handle an event asynchronously."""
        ...

    def get_handled_events(self) -> List[EventType]:
        """Get list of event types this handler can process."""
        ...

    @property
    def priority(self) -> int:
        """Handler priority."""
        ...

    @property
    def name(self) -> str:
        """Handler name."""
        ...


# ========== Event Filtering and Transformation Interfaces ==========


class EventFilterInterface(ABC, Generic[E]):
    """
    Interface for event filters that can modify or block events.

    Filters are processed before handlers and can transform or filter out events.
    """

    @abstractmethod
    def filter_event(self, event: E) -> Optional[E]:
        """
        Filter an event, potentially modifying or blocking it.

        Args:
            event: The event to filter

        Returns:
            Modified event or None to block the event
        """
        pass

    @abstractmethod
    def applies_to(self, event_type: EventType) -> bool:
        """
        Check if this filter applies to the given event type.

        Args:
            event_type: The event type to check

        Returns:
            True if this filter applies to the event type
        """
        pass


class EventTransformerInterface(ABC, Generic[E]):
    """Interface for event transformers that modify events."""

    @abstractmethod
    def can_transform(self, event: E) -> bool:
        """Check if this transformer can transform the given event."""
        pass

    @abstractmethod
    def transform(self, event: E) -> E:
        """Transform an event and return the transformed event."""
        pass


class EventValidatorInterface(ABC, Generic[E]):
    """Interface for event validators that ensure event data integrity."""

    @abstractmethod
    def validate(self, event: E) -> bool:
        """
        Validate an event's data integrity.

        Args:
            event: The event to validate

        Returns:
            True if the event is valid
        """
        pass

    @abstractmethod
    def get_validation_errors(self, event: E) -> List[str]:
        """
        Get validation errors for an event.

        Args:
            event: The event to validate

        Returns:
            List of validation error messages
        """
        pass


# ========== Event Dispatching Interfaces ==========


class EventDispatcherInterface(ABC, Generic[E]):
    """
    Core interface for event dispatchers.

    Following the Dependency Inversion Principle, high-level modules
    depend on this abstraction rather than concrete implementations.
    """

    @abstractmethod
    def register_handler(self, handler: EventHandlerInterface[E]) -> None:
        """Register an event handler."""
        pass

    @abstractmethod
    def unregister_handler(self, handler: EventHandlerInterface[E]) -> None:
        """Unregister an event handler."""
        pass

    @abstractmethod
    def register_filter(self, event_filter: EventFilterInterface[E]) -> None:
        """Register an event filter."""
        pass

    @abstractmethod
    def dispatch(self, event: E) -> Optional[E]:
        """Dispatch an event to registered handlers."""
        pass

    @abstractmethod
    def has_handlers_for(self, event_type: EventType) -> bool:
        """Check if there are handlers for a specific event type."""
        pass


class AsyncEventDispatcherInterface(ABC, Generic[E]):
    """Interface for asynchronous event dispatching."""

    @abstractmethod
    async def dispatch_async(self, event: E) -> Optional[E]:
        """Dispatch an event asynchronously."""
        pass

    @abstractmethod
    def dispatch_background(self, event: E) -> Awaitable[Optional[E]]:
        """Dispatch an event in the background."""
        pass


class BatchEventDispatcherInterface(ABC, Generic[E]):
    """Interface for batch event processing."""

    @abstractmethod
    def dispatch_batch(self, events: List[E]) -> List[Optional[E]]:
        """Dispatch multiple events at once."""
        pass

    @abstractmethod
    def dispatch_batch_async(self, events: List[E]) -> Awaitable[List[Optional[E]]]:
        """Dispatch multiple events asynchronously."""
        pass
